#ifndef CONTAINER_H
#define CONTAINER_H

/*!
 * \file      container.h
 * \brief     Abstract object container with direct accessors.
 * \author    Duriez Franck
 * \version   0.4
 */

#include <vector>
#include <list>
#include <stdexcept>

/*!
 * \class  Container
 * \brief  Abstract Object container with direct accessors.
 * \tparam Obj   : Contained Object type
 * \tparam Coord : Coordinate type for access
 *
 * This class is usefull when the container to implement have
 * strange coordinates, something like a std::list or something
 * like that, because it gives a rapid base to implement it.
 * Naturally, it can be used for simple use like mathematical
 * vector coordinates.
 */
template < class Obj, typename Coord >
class Container /*{{{*/
{
public:
	/*!
	 * \brief Constructor.
	 * \param size : maximal number of object in the Container
	 */
	Container(int size) throw(std::length_error);

	/*!
	 * \brief Destructor.
	 */
	~Container();

	/*!
	 * \brief Get the pointer to the object at coord.
	 * \param coord : Coordinate of the object in the Container
	 */
	virtual Obj* getObject(Coord coord) const = 0;

	/*!
	 * \brief Set an object at coord.
	 * \param coord  : Coordinate of the Object in the Container
	 * \param object : Pointer to the Object to put int the Container
	 */
	virtual void setObject(Coord coord, Obj* object) = 0;

	/*!
	 * \brief Swap two Objects in the container.
	 * \param coord1 : Coordinate of the first Object
	 * \param coord2 : Coordinate of the second Object
	 */
	virtual void swap(Coord coord1, Coord coord2) = 0;

	/*!
	 * \brief Apply the same function to every Object of the Container.
	 * \param process : Pointer to the function to apply
	 * \todo  Thread the elements of this function.
	 */
	void forAllObjects(void (Obj::*process)()) const;

	/*!
	 * \brief Apply the same function to every Object of the Container.
	 * \param process : Pointer to the function to apply
	 * \todo  Thread the elements of this function.
	 */
	void forAllObjects(void (Obj::*process)() const) const;

	/*!
	 * \brief Say if the Coordinate have a sense for the Container.
	 * \param coord : Coordinate to test
	 */
	virtual bool isValidCoord(Coord coord) const = 0;

protected:
	std::vector<Obj*> m_objects; ///< contained Objects*
}; /*}}}*/

#include <container.cpp>

#endif // CONTAINER_H
